1. Field of the Invention
This invention relates to components of a graphical user interface, and more specifically to device support by components of a graphical user interface.
Portions of the disclosure of this patent document may contain material that is subject to copyright protection. The copyright owner has no objection to the facsimile reproduction by anyone of the patent document or the patent disclosure as it appears in the Patent and Trademark Office file or records, but otherwise reserves all copyright rights whatsoever. Sun, Sun Microsystems, the Sun logo, Java and all Java-based trademarks and logos are trademarks or registered trademarks of Sun Microsystems, Inc. in the United States and other countries. All SPARC trademarks are used under license and are trademarks or registered trademarks of SPARC International in the United States and other countries. Products bearing SPARC trademarks are based upon an architecture developed by Sun Microsystems, Inc.
2. Background Art
A graphical user interface (GUI) is used to display information on a video display (or screen) of a computer system. A GUI typically includes screen elements such as windows, icons, labels, fields, etc. A screen element refers to both the display in a GUI and the program code that is used to generate and control the display of the screen element in the GUI. A screen element typically interacts with an operating system that is composed of one or more layers of software routines that control the physical devices that a user uses to interact with the computer system. For example, one or more input devices such as a keyboard or a pointing device (e.g., mouse, touch screen, etc.) may be used by the user. When a user generates input using one of the computer system's input devices, feedback may be provided in the GUI which is displayed by a video display to indicate that the user's input was received and is being or was processed. A problem arises when an incompatibility exists between the device capabilities and expectations of a screen element and the actual device capabilities of a computer system. For example, a screen element may support an input device that is not available in the computer system.
Most personal computers currently available provide a mouse input device that may be used to move within the GUI and over a given screen element. Mouse input that occurs within a region of the GUI occupied by a screen element may be forwarded to the screen element. The screen element processes the mouse input and may provide feedback to be displayed in the GUI. For example, the user can move within the region of the screen element in the GUI and press a button on the mouse to select the screen element. The screen element is informed that the mouse is within its region (e.g., a “mouse enter” event) and that the user has pressed a mouse button within its region (e.g., a “mouse down” event). This process is typically referred to as selecting the screen element. When a screen element is selected, the selected screen element typically becomes the focus within the GUI. For example, the display of the selected screen element can be varied from its previous display and that of the other screen elements to identify it as the currently selected screen element. Events from an input device are typically directed to the currently selected (or focused) screen element.
In the above example, it is assumed that a mouse input device is available on the computer system. Further, it is assumed that the screen element is capable of processing input received from the mouse. However, it is possible that a given input device is unavailable or that the screen element is unable to support a given input device. It would be beneficial to be able to determine the type of input devices whose input a screen element can process. That is, before device input is directed to a screen element, it would be beneficial to know whether the screen element is capable of processing the device input. Further, it may be beneficial to be able to give the look and feel of a given input device in the GUI even though that device is not physically connected to the computer system when a screen element can support that type of input device.
The problems associated with detecting whether a screen element can process device input can be better understood from a review of the Java virtual machine's processing environment and an overview of object-oriented programming.
Object-Oriented Programming
Object-oriented programming is a method of creating computer programs by combining certain fundamental building blocks, and creating relationships among and between the building blocks. The building blocks in object-oriented programming systems are called “objects.” A software application can be written using an object-oriented programming language whereby the program's functionality is implemented using these objects.
An object is a programming unit that groups together a data structure (one or more instance variables) and the operations (methods) that can use or affect that data. Thus, an object consists of data and one or more operations or procedures that can be performed on that data. The joining of data and operations into a unitary building block is called “encapsulation.”
An object can be instructed to perform one of its methods when it receives a “message.” A message is a command or instruction sent to the object to execute a certain method. A message consists of a method selection (e.g., method name) and a plurality of arguments. A message tells the receiving object what operations to perform.
One advantage of object-oriented programming is the way in which methods are invoked. When a message is sent to an object, it is not necessary for the message to instruct the object how to perform a certain method. It is only necessary to request that the object execute the method. This greatly simplifies program development.
Object-oriented programming languages are predominantly based on a “class” scheme. The class-based object-oriented programming scheme is generally described in Lieberman, “Using Prototypical Objects to Implement Shared Behavior in Object-Oriented Systems,” OOPSLA 86 Proceedings, September 1986, pp. 214-223.
An object class provides a definition for an object which typically includes both fields (e.g., variables) and methods. An object class is used to create a particular “object instance.” (The term “object” by itself is often used interchangeably to refer to a particular class or a particular instance.) An instance of an object class includes the variables and methods defined for that class. Multiple instances can be created from the same object class. Each instance that is created from the object class is said to be of the same type or class.
To illustrate, an employee object class can include “name” and “salary” instance variables and a “set_salary” method. Instances of the employee object class can be created, or instantiated for each employee in an organization. Each object instance is said to be of type “employee.” Each employee object instance includes “name” and “salary” instance variables and the “set_salary” method. The values associated with the “name” and “salary” variables in each employee object instance contain the name and salary of an employee in the organization. A message can be sent to an employee's employee object instance to invoke the “set_salary” method to modify the employee's salary (i.e., the value associated with the “salary” variable in the employee's employee object).
A hierarchy of classes can be defined such that an object class definition has one or more subclasses. A subclass inherits its parent's (and grandparent's etc.) definition. Each subclass in the hierarchy may add to or modify the behavior specified by its parent class. The parent class is also referred to as a superclass with respect to its subclass(es). Some object-oriented programming languages support multiple inheritance where a subclass may inherit a class definition from more than one parent class. Other programming languages support only single inheritance, where a subclass is limited to inheriting the class definition of only one parent class. The Java programming language also provides a mechanism known as an “interface” which comprises a set of constant and abstract method declarations. An object class can implement the abstract methods defined in an interface. Both single and multiple inheritance are available to an interface. That is, an interface can inherit an interface definition from more than one parent interface.
Java Programming Language and Program Execution
Java applications typically comprise one or more object classes and interfaces. Unlike many programming languages in which a program is compiled into machine-dependent, executable code, classes written in the Java programming language are compiled into machine independent bytecode class files. Each class contains code and data in a platform-independent format called the class file format. A bytecode includes a code that identifies an instruction (an opcode) and none or more operands to be used in executing the instruction. The computer system acting as the execution vehicle contains a program called a virtual machine, which is responsible for executing the code (i.e., bytecode) in Java programming language class files.
Applications may be designed as standalone Java applications, or as Java “applets” which are identified by an applet tag in an HTML (Hypertext Markup Language) document, and loaded by a browser application. The class files associated with an application or applet may be stored on the local computing system, or on a server accessible over a network. Each Java programming language class file is loaded into the Java virtual machine, as needed, by the “class loader.”
The classes of a Java applet are loaded on demand from the network (stored on a server), or from a local file system, when first referenced during the Java applet's execution. The virtual machine locates and loads each class file, parses the class file format, allocates memory for the class's various components, and links the class with other already loaded classes. This process makes the code in the class readily executable by the virtual machine.
Java applications and applets often make use of class libraries. Classes in the class libraries may contain what are referred to as “native methods.” A native method is a method that is comprised of native code. Bytecodes contained in a class file generated from programming statements written using the Java programming language is an example of machine-independent code. Native code typically refers to platform-dependent code. However, native code may refer to other program code. For example, native code can also be code that is written using a secondary programming language (i.e., a language other than the primary programming language used to write an application).
Applications and applets may occasionally contain classes that declare native methods. A native method declaration specifies the keyword “native,” the name of the method, the return type of the method, and any parameters that are passed to the method. In contrast to a “standard method” (i.e., non-native method) written in the Java programming language, there is no body to a native method within the respective class. Rather, the routines of a native method are carried out by compiled native code (e.g., code written in the C or C++ programming language and compiled into binary form) that is dynamically linked to a given class in the virtual machine at runtime using a linking facility specific to the given platform which supports linked libraries.
In the Solaris™ or UNIX environment, for example, the linked library containing the binary form of the native code may be implemented as a “shared object” library written as a “.so” file. In a Windows environment, the linked library may take the form of a dynamic linked (or dynamic loadable) library written as a “.dll” file. Native code may be used to perform functions otherwise not supported by the Java programming language, such as interfacing with specialized hardware (e.g., display hardware) or software (e.g., database drivers) of a given platform. Native code may also be used to speed up computationally intensive functions, such as rendering.
A class that contains a native method also contains a call to load the respective linked library:
System.loadLibrary(“Sample”);
where “Sample” is the name of the linked library, typically stored in a file named “libSample.so” or “Sample.dll”, depending on the host operating system (e.g., UNIX, Windows, etc.). The linked library is typically loaded at the time the associated class is instantiated within the virtual machine.
The linked library of native code is compiled with stub and header information of the associated class to enable the linked library to recognize the method signature of the native method in the class. The implementation of the native method is then provided as a native code function (such as a C function) in the linked library. At runtime, when a call is made to the native method, control is passed to the function in the linked library that corresponds to the called method (e.g., via pushing of a native method frame onto the native method stack). The native code within the linked library performs the function and passes control back to the Java application or applet.
In contrast to a dynamically linked library, code from a statically linked library is linked during compilation. In the Solaris environment, a statically linked library is typically stored in a file with a “.a” extension (e.g., “sample.a”). Statically linked libraries may be used instead of dynamically linked libraries where, for example, there is a limited amount of storage (e.g., a set-top box or personal data assistant).
FIG. 1 illustrates the compile and runtime environments for a processing system. In the compile environment, a software developer creates source files 100 written using the Java programming language, which contain the programmer readable class definitions, including data structures, method implementations and references to other classes. Source files 100 are provided to Java compiler 101, which compiles source files 100 into compiled “.class” (or class) files 102 that contain bytecodes executable by a Java virtual machine. Class files 102 are stored (e.g., in temporary or permanent storage) on a server, and are available for download over a network. Alternatively, class files 102 may be stored locally in a directory on the client platform.
The runtime environment contains a Java virtual machine (JVM) 105 which is able to execute bytecode class files and execute native operating system (“O/S”) calls to operating system 109 when necessary during execution. Java virtual machine 105 provides a level of abstraction between the machine independence of the bytecode classes and the machine-dependent instruction set of the underlying computer hardware 110, as well as the platform-dependent calls of operating system 109.
Class loader and bytecode verifier (“class loader”) 103 is responsible for loading bytecode class files 102 and supporting class libraries 104 written using the Java programming language into Java virtual machine 105 as needed. Class loader 103 also verifies the bytecodes of each class file to maintain proper execution and enforcement of security rules. Within the context of runtime system 108, either an interpreter 106 executes the bytecodes directly, or a “just-in-time” (JIT) compiler 107 transforms the bytecodes into machine code, so that they can be executed by the processor (or processors) in hardware 110. Native code, e.g., in the form of a linked library 111, is loaded when a class (e.g., from class libraries 104) containing the associated native method is instantiated within the virtual machine.
Interpreter 106 reads, interprets and executes a bytecode instruction before continuing on to the next instruction. JIT compiler 107 can translate multiple bytecode instructions into machine code that are then executed. Compiling the bytecodes prior to execution results in faster execution. If, for example, the same bytecode instruction is executed multiple times in a program's execution, it must be interpreted each time it is executed using interpreter 106. If JIT compiler 107 is used to compile the program, the bytecode instruction may be translated once regardless of the number of times it is executed in the program. Further, if the compilation (i.e., output of JIT compiler 107) is retained, there is no need to translate each instruction during program execution.
The runtime system 108 of virtual machine 105 supports a general stack architecture. The manner in which this general stack architecture is supported by the underlying hardware 110 is determined by the particular virtual machine implementation, and reflected in the way the bytecodes are interpreted or JIT-compiled.
FIG. 2 illustrates runtime data areas which support the stack architecture within runtime system 108. In FIG. 2, runtime data areas 200 comprise one or more thread-based data areas 207. Each thread-based data area 207 comprises a program counter register (PC REG) 208, a local variables pointer register (VARS REG) 209, a frame register (FRAME REG) 210, an operand stack pointer register (OPTOP REG) 211, a stack 212 and, optionally, a native method stack 216. Stack 212 comprises one or more frames 213 which contain an operand stack 214 and local variables 215. Native method stack 216 comprises one or more native method frames 217.
Runtime data areas 200 further comprises shared heap 201. Heap 201 is the runtime data area from which memory for all class instances and arrays is allocated. Shared heap 201 comprises method area 202, which is shared among all threads. Method area 202 comprises one or more class-based data areas 203 for storing information extracted from each loaded class file. For example, class-based data area 203 may comprise class structures such as constant pool 204, field and method data 205, and code for methods and constructors 206. Methods and constructors 206 may also be referred to as method table 206.
A virtual machine can support many threads of execution at once. Each thread has its own thread-based data area 207. At any point, each thread is executing the code of a single method, the “current method” for that thread. If the “current method” is not a native method, program counter register 208 contains the address of the virtual machine instruction currently being executed. If the “current method” is a native method, the value of program counter register 208 is undefined. Frame register 210 points to the location of the current method in method area 202.